﻿using System;
using System.Collections.Generic;
using Sudoku.Game.Abstract;
using Sudoku.Game.Concrete;

namespace Sudoku.Game
{
	class GamePresenter
	{
		private IView _view;
		private IGenerator _generator;
	    private IMaskSetter _maskSetter;
	    private Dictionary<GameDifficulty, int> _difficultMask;

		private FieldState _initialState;
	    private FieldState _fullState;
        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="view"></param>
		public GamePresenter(IView view)
		{
			_view = view;
			_generator = new FakeGenerator();
            _maskSetter = new FakeMasker();

			EventSubscribe();
            _difficultMask = new Dictionary<GameDifficulty, int>
                                 {{GameDifficulty.Easy, 27}, {GameDifficulty.Hard, 50}, {GameDifficulty.Medium, 36}};

		    NewGame(null, null);
		}
        /// <summary>
        /// активация событий
        /// </summary>
		private void EventSubscribe()
		{
 			_view.ClearUserData +=ViewClearUserData;
			_view.HelpSolution +=ViewHelpSolution;
			_view.NewGame += NewGame;
			_view.SendSolution +=ViewSendSolution;
		}
        /// <summary>
        /// проверка решения
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		void  ViewSendSolution(object sender, EventArgs e)
		{
		    string msg;
            if (_fullState.Equals(_view.GetCurrentState()))
                msg = "Поздравляем, вы правильно решили головоломку!";
            else
                msg = "Упс, похоже вы где-то ошиблись, попробуйте снова :(";
		    
            _view.ShowMessage(msg);
		}
        /// <summary>
        /// Новая игра
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		void  NewGame(object sender, EventArgs e)
		{
			var difficulty = _view.GetSettedDifficulty();
			_fullState = GenerateField(difficulty);
		    _initialState = _maskSetter.SetMask(_fullState,_difficultMask[difficulty]);
			
            _view.SetCurrentState(_initialState);
		}
        /// <summary>
        /// Подсказка
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		void  ViewHelpSolution(object sender, EventArgs e)
		{
			Coordinate coord = _view.GetActiveCellCoordinate();
			if (coord == null)
				return;
			var cell = _fullState.GetCell(coord.Horizontal,coord.Vertical);
		    _initialState.SetCell(coord.Horizontal, coord.Vertical, cell);
			_view.SetCellState(coord.Horizontal, coord.Vertical, cell);
		}
        /// <summary>
        /// Очистка данных о текущей игре
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		void  ViewClearUserData(object sender, EventArgs e)
		{
 			_view.SetCurrentState(_initialState);
		}

        /// <summary>
        /// Создание поля в зависимости от сложности
        /// </summary>
        /// <param name="difficulty"></param>
        /// <returns></returns>
        private FieldState GenerateField(GameDifficulty difficulty)
        {
            return new FieldState(_generator.GenerateField());
        }

	}
}
